<?php
require_once "word_parser_sm.php";
require_once "syn_par_sm.php";


class word_parser_Item {
	var $rowNo;
	var $txt;
	var $type;
}

function conv_spcail_str_for_debug($c) {
	switch (bin2hex($c)){
		case "0a":
			return '\n';
		case "0c":
			return '\r';
		case "20":
			return "空格";
		case "2c":
			return "逗号";
		default:
		return $c;
	}
}
	
class eApp {
	var $m_st_handler; 
	var $m_now_row;
	var $m_now_str;
	var $m_now_type;
	var $m_arr;
	var $dbg_log;
	
	function eApp($baserow) {
		$this->m_st_handler = new word_par_sm($this);
		$this->m_arr = array();
		
		$this->m_now_row = 1;
		$this->m_now_str = "";
		$this->m_now_type = "";
		$this->dbg_log = "";
		$this->_base_row = $baserow;
	}
	
	function get_result() {
		$ret = "";
		for($i = 0; $i < sizeof($this->m_arr); ++$i) {
			$ret .= "r:" . $this->m_arr[$i]->rowNo . " type:" . $this->m_arr[$i]->type . " txt:" . conv_spcail_str_for_debug($this->m_arr[$i]->txt) . "\n";  
		}
		return $ret;
	}
	
	function getchar($c) {
		if(bin2hex($c) == bin2hex("\n")) {
			++$this->m_now_row;
		}
		
		$this->dbg_log .= "char:" . conv_spcail_str_for_debug($c) . " hex:0x" . bin2hex($c) . "\n[before]cur st=" . $this->m_st_handler->getState()->getName() . "\n";
		$this->m_st_handler->getchar($c);
		$this->dbg_log .= "[after]cur st=" . $this->m_st_handler->getState()->getName() . "\n\n";
	}
	
	function doBeginItem($c, $type) {
		$this->dbg_log .= "doBeginItem() type=" .  $type . "\n";
		$this->m_now_str = $c;
		if ("" != $type) {
			$this->m_now_type = $type;
		}
	}
	
	function doAppend($c) {
		$this->dbg_log .= "doAppend()\n";
		$this->m_now_str .= $c;
	}
	
	function doSave() {
		if ("" != $this->m_now_str) {
			$this->dbg_log .= "doSave()\n";
			$it = new word_parser_Item();
			$it->rowNo = $this->m_now_row + $this->_base_row;
			$it->txt = $this->m_now_str;
			if ("" != $this->m_now_type) {
				$it->type = $this->m_now_type;	
			} else {
				
			}
			array_push($this->m_arr, $it);			
		}	
	}
	
	function set_type($t) {
		$this->dbg_log .= "set_type:" . $t . "\n";
		$this->m_now_type = $t;
	}
	
	function isChracter($c) {
	    return ((bin2hex($c) >= bin2hex('a') && bin2hex($c) <= bin2hex('z')) || (bin2hex($c) >= bin2hex('A') && bin2hex($c) <= bin2hex('Z')) || (bin2hex($c) == bin2hex('_'))) ? true : false;
	}
	
	function isNum($c) {
	    return (bin2hex($c) >= bin2hex('0') && bin2hex($c) <= bin2hex('9')) ? true : false;
	}
	
	function isBorder($c) {
	    return (((bin2hex($c) == bin2hex('{')) ||
            (bin2hex($c) == bin2hex('}')) ||
            (bin2hex($c) == bin2hex('(')) ||
            (bin2hex($c) == bin2hex(')')) ||
            (bin2hex($c) == bin2hex('[')) ||
            (bin2hex($c) == bin2hex(']')) ||
            (bin2hex($c) == bin2hex(',')) ||
            (bin2hex($c) == bin2hex(':')) ||
            (bin2hex($c) == bin2hex(';')) ||
            (bin2hex($c) == bin2hex(' ')) ||
            (bin2hex($c) == bin2hex('#')) ||
            (bin2hex($c) == bin2hex('$')) ||
            (bin2hex($c) == bin2hex("\r")) ||
            (bin2hex($c) == bin2hex("\n"))) ) ? true : false;
	}
	
	function isOperator($c) {
		return ((bin2hex($c) == bin2hex('+')) ||
            (bin2hex($c) == bin2hex('-')) ||
            (bin2hex($c) == bin2hex('*')) ||
            (bin2hex($c) == bin2hex('/')) ||
            (bin2hex($c) == bin2hex('^')) ||
            (bin2hex($c) == bin2hex('%')) ||
            (bin2hex($c) == bin2hex('>')) ||
            (bin2hex($c) == bin2hex('<')) ||
            (bin2hex($c) == bin2hex('=')) ||
            (bin2hex($c) == bin2hex('!')) ||
            (bin2hex($c) == bin2hex('&')) ||
            (bin2hex($c) == bin2hex('|'))) ? true: false;
	}
	
	function printError($c) {
		print "char:" . $c . ",  at row:" . $this->m_now_row . ", Error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.\n";
	}
}

class eItem {
	var $rowNo;
	var $txt;
	var $type;
	var $val;
}

class e_app_syntax {
	var $data_pool;
	var $rs_arr;//result array, type of eItem*
	var $st_hdl;
	var $_rsItem;
	var $dbg_log;
	var $_tab_cnt;
	
	function e_app_syntax($dp) {
		$this->data_pool = $dp;
		$this->rs_arr = array();
		$this->st_hdl = new syntax_par_sm($this);
		$this->dbg_log = "";
		$this->_tab_cnt = 0;
	}
	
	function getItem($i) {
		$this->dbg_log .= "item type:" . $i->type . ", content:" . conv_spcail_str_for_debug($i->txt) . "\n[before]cur st=" . $this->st_hdl->getState()->getName() . "\n";
		$this->st_hdl->getItem($i);
		$this->dbg_log .= "[after]cur st=" . $this->st_hdl->getState()->getName() . "\n\n";
	}
	
	function syn_parse() {
		$this->st_hdl->enterStartState();
		for($i = 0; $i < sizeof($this->data_pool); ++$i) {
			$this->getItem($this->data_pool[$i]);  
		}
	}
	
	function get_result($word_app) {
		$ret = '<p><a href="#" id="i_wp_dbglog">查看词法解析中间log</a>  	&ensp; <a href="#" id="i_wp_result">查看词法解析结果</a> 	&ensp; <a href="#" id="i_sp_dbglog">查看语法中间log</a></p><table id="customers" style="width:800px;"><tr>
			<th style="text-align:center;">原行号</th>
			<th style="text-align:center;">Item</th>
			<th style="text-align:center;">枚举值</th>
			<th style="text-align:center;">枚举值(Hex)</th>
			</tr>';
		for($i = 0; $i < sizeof($this->rs_arr); ++$i) {
			//$ret .= "r:" . $this->rs_arr[$i]->rowNo . " value:" . $this->rs_arr[$i]->val . " txt:" . conv_spcail_str_for_debug($this->rs_arr[$i]->txt) . "\n";
			++$this->_tab_cnt;
			if ($this->_tab_cnt % 2) {
				$ret .= "<tr>";
			} else {
				$ret .= '<tr class="alt">';				
			}
			$ret .= '<td>' . $this->rs_arr[$i]->rowNo . '</td>
				<td>' . conv_spcail_str_for_debug($this->rs_arr[$i]->txt) . '</td>
				<td>'. $this->rs_arr[$i]->val . '</td>
				<td>0x'. dechex($this->rs_arr[$i]->val) . '</td>
				</tr>';
		}
		$ret .= '</table>';
		$ret .= '<div id="i_word_parser_debug_log" style="display:none; ">' . $word_app->dbg_log . '</div>';
		$ret .= '<div id="i_word_parser_result" style="display:none; ">' . $word_app->get_result() . '</div>';
		$ret .= '<div id="i_syntax_debug_log" style="display:none; ">' . $this->dbg_log . '</div>';
		return $ret;
	}
	
	function write_rs($it_word) {
		$this->dbg_log .= "write_rs()\n";
		$this->_rsItem = new eItem();
		$this->_rsItem->rowNo = $it_word->rowNo;
		$this->_rsItem->txt = $it_word->txt;
		$this->_rsItem->type = $it_word->type;
		$this->_rsItem->val = -1;
	}
	
	function calc_value($it_word) {
		$this->dbg_log .= "calc_value()\n";
		if ("num" == $it_word->type) {
			$this->_rsItem->val = $it_word->txt;
		} else if ("," == $it_word->txt) {
			if(0 == sizeof($this->rs_arr)) {
				$this->_rsItem->val = 0;	
			} else {
				$this->_rsItem->val = $this->rs_arr[sizeof($this->rs_arr) - 1]->val + 1;
			}
			
		} else if ("char" == $it_word->type) {
			$this->_rsItem->val = $this->get_value_by_look_back($it_word->txt);
		}
		array_push($this->rs_arr, $this->_rsItem);
	}
	
	function get_value_by_look_back($q_cond) {
		for ($i = 0; $i < sizeof($this->rs_arr); ++$i) {
			if ($q_cond == $this->rs_arr[$i]->txt) {
				return $this->rs_arr[$i]->val;
			}
		}
		return -2;
	}
	
	function printError($iw) {
		print "iw:" . $iw->txt . ",  at row:" . $iw->rowNo . ", Error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.\n";
	}
}
	
	function pre_request(){
		print '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
		<html>
		    <head>
				<meta charset="utf-8" />
				<title>enum parser</title>
				<script src="jquery-1.10.2.min.js"></script>
				<script>
					$(document).ready(function(){
						$("#i_set_sample").click(function(){$("#ita1").val($("#i_enum_sample").text());});
						$("#ita1").focus(function(){if($(this).attr("title") == "请输入待处理文本") {$(this).val("");}});
						$("#ita1").change(function(){$(this).attr("title", "再次输入待处理文本,然后点击提交按钮");});
						$("#ibtnsubmit").click(function(){ 
							$.post(
									"enum_parser.php",
									{
										name:"enum_parser",
										cont:$("#ita1").val(),
										base_row:$("#i_base_row").val(),
									},
									function(data, status) {
										$("#i_fanl_rs").html(data);
										$("#i_wp_dbglog").click(function(){$("#i_dbug_area").css("display", "inline");$("#ita2").val($("#i_word_parser_debug_log").text());});
										$("#i_wp_result").click(function(){$("#i_dbug_area").css("display", "inline");$("#ita2").val($("#i_word_parser_result").text());});
										$("#i_sp_dbglog").click(function(){$("#i_dbug_area").css("display", "inline");$("#ita2").val($("#i_syntax_debug_log").text());});
									}
							)
				
						});
					});
				</script> 
						
<style type="text/css">
#customers
  {
  font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
  width:100%;
  border-collapse:collapse;
  }

#customers td, #customers th 
  {
  font-size:1em;
  border:1px solid #98bf21;
  padding:3px 7px 2px 7px;
  }

#customers th 
  {
  font-size:1.1em;
  text-align:left;
  padding-top:5px;
  padding-bottom:4px;
  background-color:#A7C942;
  color:#ffffff;
  }

#customers tr.alt td 
  {
  color:#000000;
  background-color:#EAF2D3;
  }
</style>
			</head>
			<body>
				<div id="1">
					<div style="display:inline; ">数据输入区 &ensp;&ensp;&ensp;<span style="font-size:80%; "><a id="i_set_sample" href="#">点击以设置测试示例</a></span><br/><textarea id="ita1" style="width:40%; height:300px;" title="请输入待处理文本">请将待处理的enum文本贴在本框中.'. "\n" . '注意是从enum之后的花括号之间的文本内容</textarea></div>
					<div id="i_dbug_area" style="display: none; "><textarea id="ita2" style="width:40%; height:300px;"></textarea></div><br/>
					<lable>输入基础行号(如210)</lable><input type="text" id="i_base_row"/>
				</div>
				<button id="ibtnsubmit">提交</button>
				<div id="i_fanl_rs"></div>
				<div id="i_enum_sample" style="display: none; ">MODE_GUI_MSGID_CLEAR, //这里是注释' . "\nMODE_GUI_MSGID_INFO_CLOCKSET, /* 時計を設定してください  */\n" . "MODE_GUI_MSGID_INFO_HOGO_ON =16,\n" . "MODE_GUI_MSGID_X1 ,\n" . "MODE_GUI_MSGID_X2,\n" . " MODE_GUI_MSGID_X3 = MODE_GUI_MSGID_X1,\nMODE_GUI_MSGID_X4,\n" . "MODE_GUI_MSGID_X5," . '</div>
			</body>
		        
		';
	}
	
	if ("enum_parser" == $_POST["name"]) {
		$a = $_POST["cont"];
		$spt = str_split($a, 1);
		$bsr = $_POST["base_row"];
		
		$app = new eApp($bsr);
		$app->m_st_handler->enterStartState();
		
		for($i = 0; $i < sizeof($spt); ++$i) {
			$app->getchar($spt[$i]);
		} 
		$app->doSave();
		
		$app_syntax = new e_app_syntax($app->m_arr);
		$app_syntax->syn_parse();
		
		print $app_syntax->get_result($app);		
	} else {
		pre_request();	
	}

?>